#pragma once

namespace vex {
    namespace iterable {
        struct trivial_range_tag {};
        struct output_range_tag : public trivial_range_tag {};
        struct one_pass_range_tag : public trivial_range_tag {};
        struct forward_range_tag : public one_pass_range_tag {};
        struct bidirectional_range_tag : public forward_range_tag {};
        struct random_access_range_tag : public bidirectional_range_tag {};

        typedef trivial_range_tag trivial_tag;
        typedef output_range_tag output_tag;
        typedef one_pass_range_tag one_pass_tag;
        typedef forward_range_tag forward_tag;
        typedef bidirectional_range_tag bidirectional_tag;
        typedef random_access_range_tag random_access_tag;

        typedef trivial_range_tag trivial;
        typedef output_range_tag output;
        typedef one_pass_range_tag one_pass;
        typedef forward_range_tag forward;
        typedef bidirectional_range_tag bidirectional;
        typedef random_access_range_tag random_access;
    }

    using iterable::trivial_range_tag;
    using iterable::output_range_tag;
    using iterable::one_pass_range_tag;
    using iterable::forward_range_tag;
    using iterable::bidirectional_range_tag;
    using iterable::random_access_range_tag;

    using iterable::trivial_tag;
    using iterable::output_tag;
    using iterable::one_pass_tag;
    using iterable::forward_tag;
    using iterable::bidirectional_tag;
    using iterable::random_access_tag;
}